package main

import (
	"fmt"
	"github.com/ngaut/log"
	"os"
	"os/signal"
	"runtime"
	"runtime/debug"
	"syscall"
	"time"
)

//https://colobu.com/2016/12/21/how-to-dump-goroutine-stack-traces/
// 暴露一个命令、api,或者捕捉信号，来获得栈桢
func main() {
	T_use_printstack_or_pprof()
	//T_use_signal()
	//Dummy("")
}

func T_use_signal()  {
	dumpStacks := func() {
		buf := make([]byte, 16384)
		runtime.Stack(buf, true)
		//buf = buf[:runtime.Stack(buf, true)]
		fmt.Printf("=== begin \n%s\nend", buf)
	}

	setupSigusr1Trap := func() {
		c := make(chan os.Signal, 1)
		fmt.Println("before notify")
		signal.Notify(c, syscall.SIGUSR1) //当前goroutine接收信号SIGUSR1，发送到channel
		fmt.Println("after nofity")
		go func() {
			for range c {
				log.Info("range c ...")
				dumpStacks()
			}
		}()
	}

	setupSigusr1Trap()
	go a()
	u1()
}

///////////////////////////////////////
func T_use_printstack_or_pprof()  {
	go a()
	m1()
}
func m1() {
	m2()
}
func m2() {
	m3()
}
func m3() {
	debug.PrintStack() //打印当前这个goroutine的栈桢
	//pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) //打印所有goroutine栈桢
	time.Sleep(time.Hour)
}
func a() {
	time.Sleep(time.Hour)
}

func u1()  {
	u2()
}
func u2()  {
	time.Sleep(time.Hour)
}